﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

namespace Distrackting.BusinessLayer
{
    public enum UnitsOfLength { Mile, NauticalMiles, Kilometer };

    public class Coordenadas
    {
        private double latitude, longitude;

        /// <summary>
        /// Latitude in degrees. -90 to 90
        /// </summary>
        public Double Latitude
        {
            get { return latitude; }
            set
            {
                if (value > 90) throw new ArgumentOutOfRangeException("value", "Latitude value cannot be greater than 90.");
                if (value < -90) throw new ArgumentOutOfRangeException("value", "Latitude value cannot be less than -90.");
                latitude = value;
            }
        }

        /// <summary>
        /// Longitude in degree. -180 to 180
        /// </summary>
        public Double Longitude
        {
            get { return longitude; }
            set
            {
                if (value > 180) throw new ArgumentOutOfRangeException("value", "Longitude value cannot be greater than 180.");
                if (value < -180) throw new ArgumentOutOfRangeException("value", "Longitude value cannot be less than -180.");
                longitude = value;
            }
        }

    }
    public static class CoordenadasMethods{
        private const Double _MilesToKilometers = 1.609344;
        private const Double _MilesToNautical = 0.8684;

        /// <summary>
        /// Converts degrees to Radians.
        /// </summary>
        /// <returns>Returns a radian from degrees.</returns>
        public static Double ToRadian(this Double degree) { return (degree * Math.PI / 180.0); }
        /// <summary>
        /// To degress from a radian value.
        /// </summary>
        /// <returns>Returns degrees from radians.</returns>
        public static Double ToDegree(this Double radian) { return (radian / Math.PI * 180.0); }

  
        /// <summary>
        /// Calculates the distance between two points of latitude and longitude.
        /// Great Link - http://www.movable-type.co.uk/scripts/latlong.html
        /// </summary>
        /// <param name="Coordenadas1">First Coordenadas.</param>
        /// <param name="Coordenadas2">Second Coordenadas.</param>
        /// <param name="unitsOfLength">Sets the return value unit of length.</param>
        public static Double Distance(Coordenadas Coordenadas1, Coordenadas Coordenadas2, UnitsOfLength unitsOfLength)
        {

            var theta = Coordenadas1.Longitude - Coordenadas2.Longitude;
            var distance = Math.Sin(Coordenadas1.Latitude.ToRadian()) * Math.Sin(Coordenadas2.Latitude.ToRadian()) +
                           Math.Cos(Coordenadas1.Latitude.ToRadian()) * Math.Cos(Coordenadas2.Latitude.ToRadian()) *
                           Math.Cos(theta.ToRadian());

            distance = Math.Acos(distance);
            distance = distance.ToDegree();
            distance = distance * 60 * 1.1515;

            if (unitsOfLength == UnitsOfLength.Kilometer)
                distance = distance * _MilesToKilometers;
            else if (unitsOfLength == UnitsOfLength.NauticalMiles)
                distance = distance * _MilesToNautical;

            return (distance);

        }


    }


}
